#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>

#include "driver_uart.h"
#include "hal_debug.h"



unsigned char s_bufTx[CONSOLE_TX_BUF_SIZE];



char HexToString(unsigned int hexData, unsigned char hexBitNum, char* str)
{
    signed char result = 0;
    char bit = 0;
    bit = hexBitNum;

    for (; bit > 0; bit--)
    {
        result = (hexData >> (4 * (bit - 1))) & 0xf;

        if (result >= 0 && result <= 9)
        {
            str[hexBitNum - bit] = result + '0';
        }
        else if (result >= 10 && result <= 15)
        {
            str[hexBitNum - bit] = result - 10 + 'A';
        }
    }
    return hexBitNum;
}



char HexGroupToString(uint8_t* hex, unsigned char hexNum, uint8_t* str, char separator)
{
    unsigned char i;

    for (i = 0; i < hexNum; i++)
    {
        HexToString((char)hex[i], 2, (char*)str + i * 3);
        str[i * 3 + 2] = separator;
    }
    return 0;
}



void Console_HexGrounpOut(uint8_t* hexGroup, uint16_t len, char separator)
{
    if (3 * len + 3 + 3 > CONSOLE_TX_BUF_SIZE)
    {
        len = (CONSOLE_TX_BUF_SIZE / 3) - 1 - 1;
    }

    s_bufTx[0] = '[';

    HexGroupToString(hexGroup, len, (uint8_t*)s_bufTx + 1, separator);

    if (len == (CONSOLE_TX_BUF_SIZE / 3) - 1 - 1)
    {
        memcpy(s_bufTx + 3 * len + 1, "...", 3);

        s_bufTx[3 * len + 3 + 1] = ']';
        s_bufTx[3 * len + 3 + 2] = '\r';
        s_bufTx[3 * len + 3 + 3] = '\n';

        uart_log_send((const char*)s_bufTx, 3 * len + 3 + 3);
    }
    else
    {
        s_bufTx[3 * len] = ']';
        s_bufTx[3 * len + 1] = '\r';
        s_bufTx[3 * len + 2] = '\n';

        uart_log_send((const char*)s_bufTx, 3 * len + 3);
    }
}


void uart_log_send(const char* str_buf, uint16_t length)
{
    if (1)
    {
        for (uint32_t i = 0; i < length; i++)
        {
            driver_uart0_send_byte(str_buf[i]);
        }
    }
    else
    {
        for (uint32_t i = 0; i < length; i++)
        {
            driver_uart1_send_byte(str_buf[i]);
        }
    }
}


void uart_log_printf(const char* strFormat, ...)
{
    va_list args;
    uint16_t Length;

    /* Write out the Data. */
    va_start(args, strFormat);

    Length = vsnprintf((char*)s_bufTx, (sizeof(s_bufTx) - 1), strFormat, args);
    va_end(args);

    uart_log_send((const char*)s_bufTx, Length);
}



void Hexdump_Printf(uint8_t* hexGroup, uint16_t len, char separator)
{
#if ENABLE_HEX_DUMP_LOG
    Console_HexGrounpOut(hexGroup, len, separator);
#endif
}

void Hexdump_Debug(uint8_t* hexGroup, uint16_t len, char separator)
{
#if ENABLE_DEBUG_LOG
    Console_HexGrounpOut(hexGroup, len, separator);
#endif
}




